package git.etl.eval;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

import git.etl.ExprParseException;
import git.etl.ExprEvalTask.EetJobD;
import git.etl.eval.IEvaluator.IFunction;
import git.etl.eval.IEvaluator.ILex;

/**
 * sum factor 1 by factor (2,N); then match it to every element in base
 */
public class FuncSumby
	implements IFunction
{
	@Override
	public Map<List<String>, BigDecimal[]> perform(
			Map<List<String>, BigDecimal[]> base, ILex lex, EetJobD t,
			IEvaluator owner)
		throws Exception
	{
		String w = lex.nextElement();
		if (!"(".equals(w))
			throw new ExprParseException("'('", w);
		
		w = lex.nextElement();
		Map<List<String>, BigDecimal[]> dv = owner.resolveSymbol(w, lex, t, base);		
   		Map<List<String>, BigDecimal[]> b = new HashMap<List<String>, BigDecimal[]>();
		List<String> k;
		HashSet<String> si = new HashSet<String>();
		
		while(!")".equals(w = lex.nextElement()))
		{
			if (!",".equals(w))
				throw new ExprParseException(",", w);
			
			w = lex.nextElement();
			si.add(w);
		}
		
		for (Map.Entry<List<String>, BigDecimal[]> en : dv.entrySet())
		{
			k = new ArrayList<String>(en.getKey());
			for (int i = 0; i < k.size(); ++i)
			{
				if (!si.contains(String.valueOf(i)) && !"".equals(k.get(i)))
					k.set(i, "");
			}
			
			BigDecimal[] s = en.getValue();
			BigDecimal[] n = b.get(k);
			if (null == n)
			{
    			n = new BigDecimal[s.length];
    			for (int i = 0; i < n.length; ++i)
    			{
    				n[i] = s[i];
    			}
    			b.put(k, n);
			}
			else
			{
    			for (int i = 0; i < n.length; ++i)
    			{
    				n[i] = n[i].add(s[i]);
    			}
			}
		}
		
		return FuncJoin.join(base, b, si);
	}
}
